﻿using Microsoft.Extensions.Logging;
using MiniJob.Jobs;
using System.Net.Mime;
using System.Text;
using System.Text.Json;

namespace MiniJob.Worker.Jobs;

/// <summary>
/// HTTP 处理器
/// </summary>
public class HttpJob(IHttpClientFactory clientFactory) : Job
{
    protected override async Task<JobResult> DoWorkAsync(JobContext taskContext, CancellationToken cancellationToken = default)
    {

        var para = taskContext.GetParams();
        if (para.IsNullOrWhiteSpace())
        {
            return JobResult.ErrorMessage("params is null.");
        }

        var httpParams = JsonSerializer.Deserialize<HttpParams>(para)!;

        if (httpParams.Url.IsNullOrEmpty())
            return new JobResult(false, "URL cant't be empty!");

        if (!httpParams.Url.StartsWith("http"))
            httpParams.Url = "http://" + httpParams.Url;

        Logger.LogInformation("request url: {Url}", httpParams.Url);

        // set default method
        if (httpParams.Method == null)
        {
            httpParams.Method = HttpMethod.Get;
            Logger.LogInformation("using default request method: GET");
        }
        else
        {
            Logger.LogInformation("request method: {Method}", httpParams.Method);
        }

        // default timeout
        Logger.LogInformation("request timeout: {Timeout} seconds", httpParams.Timeout.TotalSeconds);

        // set default mediaType
        if (httpParams.MediaType.IsNullOrEmpty() && httpParams.Method != HttpMethod.Get)
        {
            httpParams.MediaType = MediaTypeNames.Application.Json;
            Logger.LogWarning($"try to use '{MediaTypeNames.Application.Json}' as media type");
        }

        // build http
        var httpClient = clientFactory.CreateClient();
        httpClient.Timeout = httpParams.Timeout;

        if (httpParams.Headers != null)
        {
            foreach (var item in httpParams.Headers)
            {
                httpClient.DefaultRequestHeaders.Add(item.Key, item.Value);
                Logger.LogInformation("add header {Key}:{Value}", item.Key, item.Value);
            }
        }

        HttpRequestMessage httpRequest = new(httpParams.Method, httpParams.Url);
        if (!httpParams.Body.IsNullOrWhiteSpace())
        {
            httpRequest.Content = new StringContent(httpParams.Body, Encoding.Default, httpParams.MediaType);
        }
        var httpResponse = await httpClient.SendAsync(httpRequest, cancellationToken);

        if (httpResponse.IsSuccessStatusCode)
        {
            var msg = await httpResponse.Content.ReadAsStringAsync(cancellationToken);

            return new JobResult(true, msg);
        }
        else
        {
            return new JobResult(false, httpResponse.ReasonPhrase);
        }
    }
}
